#ifndef GAMEENGINE_UNIT_TEST_H
#define GAMEENGINE_UNIT_TEST_H

#include <GameEngine/UnitTest/unit_test_settings.h>

#include <GameEngine/Core/Memory/memory_manager.h>

#include <iostream>


#ifdef GAMEENGINE_NAMESPACES
namespace GameEngine {
#endif

//! Print on error message indicating on which line and file the error occurred, if such an error occurred
/*!
 @param error The code associated to the error (most often, this will be a string)
 @param line The line where the error occurred
 @param file The file where the error occurred
 @param value True if an error occurred, false otherwise
 @return True if an error occurred, false otherwise
 */
template <class T> bool print(const T& error, const char* line, const char* file, bool value) {
	if ( value == false ) {
		std::cerr << error << std::endl
			<< "	[Line " << line << "]" << std::endl
			<< "	[File " << file << "]" << std::endl;
	}
	return value;
}

//! Forces the expansion of the macros in parameter x
#define GAMEENGINE_TXT_MACRO_INTERNAL(x) #x

//! Expand the macros in parameter x
#define GAMEENGINE_TXT_MACRO(x) GAMEENGINE_TXT_MACRO_INTERNAL(x)

//! Macro used to print on error message indicating on which line and file the error occurred
#define UNIT_TEST_ERROR(error, value) print(error, GAMEENGINE_TXT_MACRO(__LINE__), GAMEENGINE_TXT_MACRO(__FILE__), value)


//! Class in charge of performing unit tests
class _UnitTest_decl UnitTest {

public:
	static bool test();
	static bool force_test();

	static bool test_ai_funnel_functions();

	static bool test_core_rtti_functions();
	static bool test_core_factory_functions();
	static bool test_core_graph_functions();
	static bool test_core_quadtree_functions();
	static bool test_core_octree_functions();

	static bool test_maps_displacement_iterator_functions();

	static bool test_geometry_halfedge_trgl_mesh_functions();

	template <class T> static bool test_geometry_angle_functions();
	template <class T> static bool test_geometry_box2d_functions();
	template <class T> static bool test_geometry_box3d_functions();
	template <class T> static bool test_geometry_circle2d_functions();
	template <class T> static bool test_geometry_circle3d_functions();
	template <class T> static bool test_geometry_hexagon2d_functions();
	template <class T> static bool test_geometry_line2d_functions();
	template <class T> static bool test_geometry_line3d_functions();
	template <class T> static bool test_geometry_sphere_functions();
	template <class T> static bool test_geometry_trgl2d_functions();
	template <class T> static bool test_geometry_trgl2dfast_functions();
	template <class T> static bool test_geometry_trgl3d_functions();
	template <class T> static bool test_geometry_trgl3dfast_functions();
	template <class T> static bool test_geometry_transformer2d_functions();
	template <class T> static bool test_geometry_transformer3d_functions();
	template <class T> static bool test_geometry_transformer2d_orientation_functions();
	template <class T> static bool test_geometry_transformer3d_orientation_functions();
};


#ifdef GAMEENGINE_NAMESPACES
} // namespace GameEngine
#endif

#include <GameEngine/UnitTest/ut_geometry_angle.hpp>
#include <GameEngine/UnitTest/ut_geometry_box2d.hpp>
#include <GameEngine/UnitTest/ut_geometry_box3d.hpp>
#include <GameEngine/UnitTest/ut_geometry_circle2d.hpp>
#include <GameEngine/UnitTest/ut_geometry_circle3d.hpp>
#include <GameEngine/UnitTest/ut_geometry_hexagon2d.hpp>
#include <GameEngine/UnitTest/ut_geometry_line2d.hpp>
#include <GameEngine/UnitTest/ut_geometry_line3d.hpp>
#include <GameEngine/UnitTest/ut_geometry_transformer2d_orientation.hpp>
#include <GameEngine/UnitTest/ut_geometry_transformer3d_orientation.hpp>
#include <GameEngine/UnitTest/ut_geometry_sphere.hpp>
#include <GameEngine/UnitTest/ut_geometry_transformer2d.hpp>
#include <GameEngine/UnitTest/ut_geometry_transformer3d.hpp>
#include <GameEngine/UnitTest/ut_geometry_trgl2d.hpp>
#include <GameEngine/UnitTest/ut_geometry_trgl2dfast.hpp>
#include <GameEngine/UnitTest/ut_geometry_trgl3d.hpp>
#include <GameEngine/UnitTest/ut_geometry_trgl3dfast.hpp>

#endif
